package com.core.family.biz.yizhao.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.core.common.cons.RespCode;
import com.core.common.exception.BDException;
import com.core.common.manger.wechat.WxOrderService;
import com.core.common.utils.MyRandomUtil;
import com.core.family.admin.Interceptor.UserUtil;
import com.core.family.admin.config.AuthProperties;
import com.core.family.admin.domain.po.PlatFinanceStatement;
import com.core.family.admin.domain.po.PlatPayment;
import com.core.family.admin.service.PlatFinanceStatementService;
import com.core.family.admin.service.PlatPaymentService;
import com.core.family.biz.yizhao.domain.dto.YzUserDto;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import com.core.family.biz.yizhao.mapper.YzWalletMapper;
import com.core.family.biz.yizhao.domain.po.YzWallet;
import com.core.family.biz.yizhao.service.YzWalletService;
import com.core.common.gen.BaseServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;


/**
 * @author honglei
 * @version 1.0
 * @time: 2023-7-13 15:03:24
 * @Description 服务实现层 钱包表
 */
@Slf4j
@Service
public class YzWalletServiceImpl extends BaseServiceImpl<YzWalletMapper,YzWallet> implements YzWalletService{
    @Autowired
    private WxOrderService wxOrderService;

    @Autowired
    PlatPaymentService paymentService;
    @Resource
    AuthProperties authProperties;

    @Override
    public YzWallet getByUserId(int userId) {
        LambdaQueryWrapper<YzWallet> wrapper=Wrappers.lambdaQuery();
        wrapper.eq(YzWallet::getUserId,userId);
        return this.baseMapper.selectOne(wrapper);
    }


    /***
     * 錢包交易
     * @param userId
     * @param amount
     * @return
     */
    @Override
    public YzWallet amountChange(int userId, long amount) {
        YzWallet walletFr=getByUserId(userId);
        if (Objects.isNull(walletFr)){
            log.error("用户 {} 钱包不存在",userId);
            throw new BDException("用户钱包不存在");
        }
        long totalAmount=walletFr.getAmount()+amount;
        if (0 > totalAmount){
            throw new BDException("执行后金额错误");
        }
        walletFr.setAmount(totalAmount);
        updateById(walletFr);
        return walletFr;
    }


    /***
     * 解凍凍結款
     * @param userId
     * @param amount
     * @return
     */
    @Override
    public YzWallet unFrozenAmount(int userId, long amount) {
        YzWallet walletFr=getByUserId(userId);
        if (Objects.isNull(walletFr)){
            log.error("用户 {} 钱包不存在",userId);
            throw new BDException("用户钱包不存在");
        }
        if (amount > walletFr.getFrozenAmount()){
            log.error("用户 {} 待解冻不足",userId);
            throw new BDException("待解冻不足无法解冻");
        }
        if (0 > amount){
            throw new BDException("解冻金额错误");
        }
        walletFr.setFrozenAmount(walletFr.getFrozenAmount()-amount);
        walletFr.setAmount(walletFr.getAmount()+amount);
        updateById(walletFr);
        return walletFr;
    }
    @Autowired
    PlatFinanceStatementService statementService;
    @Override
    public WxPayMpOrderResult h5pay(Map<String, String> map, HttpServletRequest request) {
        String token = request.getHeader(authProperties.getTokenName());
        YzUserDto userDto= UserUtil.getYzUserDetailByToken(token);
        if (null==userDto){
            throw new  BDException(RespCode.UNLOGIN);
        }
        String outTradeNo=map.get("outTradeNo");
        if (StringUtils.isEmpty(outTradeNo)){
            outTradeNo= MyRandomUtil.randomOnlySn();
        }
        Integer totalFee=Integer.valueOf(map.get("totalFee"));

        PlatFinanceStatement finance=new PlatFinanceStatement()
                .setUserId(userDto.getId())
                .setUserName(userDto.getUsername())
                .setBizType("充值")
                .setType("支入")
                .setOrderDis("支付:"+outTradeNo)
                .setPrice(totalFee.longValue())
                .setPayTime(new Date())
                .setPaySn(outTradeNo)
                .setAuditStatus("--");


        /* 生成賬單*/
        statementService.save(finance);

        /*生成微信预支付订单*/
        WxPayMpOrderResult result= (WxPayMpOrderResult) wxOrderService.h5pay(outTradeNo,totalFee, request);

        /*生成支付流水*/
        PlatPayment payment=new PlatPayment();
        payment.setFinanceId(finance.getId());
        payment.setPaySn(outTradeNo);
        payment.setPayWay("微信");
        payment.setPayType("支付");
        payment.setAmount(totalFee);
        paymentService.save(payment);


        return result;
    }




    @Transactional
    @Override
    public WxPayMpOrderResult walletRecharge(Map<String, String> map, HttpServletRequest request) {
        String token = request.getHeader(authProperties.getTokenName());
        YzUserDto userDto= UserUtil.getYzUserDetailByToken(token);
        if (null==userDto){
            throw new  BDException(RespCode.UNLOGIN);
        }
        if (Objects.isNull(userDto.getOpenid())){
            throw new  BDException("该用户未绑定微信");
        }
        String outTradeNo=map.get("outTradeNo");
        if (StringUtils.isEmpty(outTradeNo)){
            outTradeNo= MyRandomUtil.randomOnlySn();
        }
        Integer totalFee=Integer.valueOf(map.get("totalFee"));
        String openid=userDto.getOpenid();

        PlatFinanceStatement finance=new PlatFinanceStatement()
                .setUserId(userDto.getId())
                .setUserName(userDto.getUsername())
                .setBizType("充值")
                .setType("支入")
                .setOrderDis("支付:"+outTradeNo)
                .setPrice(totalFee.longValue())
                .setPayTime(new Date())
                .setPaySn(outTradeNo)
                .setAuditStatus("--");


       /* 生成賬單*/
        statementService.save(finance);



        /*生成微信预支付订单*/
        WxPayMpOrderResult result= (WxPayMpOrderResult) wxOrderService.prepay(outTradeNo,openid,totalFee, request);

        /*生成支付流水*/
        PlatPayment payment=new PlatPayment();
        payment.setFinanceId(finance.getId());
        payment.setPaySn(outTradeNo);
        payment.setPayWay("微信");
        payment.setPayType("支付");
        payment.setAmount(totalFee);
        paymentService.save(payment);


        return result;
    }


    @Override
    public PlatFinanceStatement walletRefund(Map<String, String> map, HttpServletRequest request) {
        String token = request.getHeader(authProperties.getTokenName());
        YzUserDto userDto= UserUtil.getYzUserDetailByToken(token);
        if (null==userDto){
            throw new  BDException(RespCode.UNLOGIN);
        }
        String outTradeNo=map.get("outTradeNo");
        String outRefundNo=map.get("outRefundNo");
        Integer totalFee=Integer.valueOf(map.get("totalFee"));

        PlatFinanceStatement financedb=statementService.getby(outTradeNo);


        if (Objects.isNull(financedb)){
            throw new  BDException("原订单不存在");
        }

        if (StringUtils.isEmpty(outRefundNo)){
            outRefundNo= MyRandomUtil.randomOnlySn();
        }
        String openid=userDto.getOpenid();

        PlatFinanceStatement finance=new PlatFinanceStatement()
                .setUserId(financedb.getUserId())
                .setUserName(financedb.getUserName())
                .setBizType("退款")
                .setType("支出")
                .setOrderDis("退款:"+outRefundNo)
                .setPrice(totalFee.longValue())
                .setPayTime(new Date())
                .setPaySn(outRefundNo)
                .setOutTradeno(outTradeNo)
                .setJoinId(financedb.getId())
                .setAuditStatus("待审核");


        /* 生成賬單*/
        statementService.save(finance);

        /*生成微信预支付订单*/
     //   WxPayMpOrderResult result= (WxPayMpOrderResult) wxOrderService.prepay(outTradeNo,openid,totalFee, request);

        /*生成支付流水*/
        PlatPayment payment=new PlatPayment();
        payment.setFinanceId(finance.getId());
        payment.setPaySn(outTradeNo);
        payment.setPayWay("微信");
        payment.setPayType("退款");
        payment.setAmount(totalFee);
        payment.setRefundNo(outRefundNo);
        paymentService.save(payment);

        return null;
    }

    /***
     * 钱包 余额转账
     * @param userIdFr
     * @param userIdTo
     * @param amount
     * @param frozen
     * @return
     */
    @Transactional
    @Override
    public boolean deduct(int userIdFr, int userIdTo, long amount, boolean frozen) {

        YzWallet walletFr=getByUserId(userIdFr);
        if (Objects.isNull(walletFr)){
            log.error("用户 {} 钱包不存在",userIdFr);
            throw new BDException("用户钱包不存在");
        }
        if (amount > walletFr.getAmount()){
            log.error("用户 {} 钱包余额不足",userIdFr);
            throw new BDException("用户钱包余额不足无法扣减");
        }
        if (0 > amount){
            throw new BDException("转账金额错误");
        }
        walletFr.setAmount(walletFr.getAmount()-amount);


        YzWallet walletTo=getByUserId(userIdTo);
        if (Objects.isNull(walletTo)){
            log.error("用户 {} 钱包不存在",userIdTo);
            throw new BDException("用户钱包不存在");
        }
        if (frozen){
            walletTo.setFrozenAmount(walletTo.getFrozenAmount()+amount);
            amount=0;
        }
        walletTo.setAmount(walletTo.getAmount()+amount);

        updateById(walletFr);
        updateById(walletTo);
        return true;
    }


}

